﻿using System;

namespace TaskGenerater
{
    public static class Templete
    {
        public static string MergeFile(string classString)
        {
            return FileTemplate.Trim()
                .Replace("{class}", classString);
        }

        public static string MergeClass(Generater data)
        {
            return ClassTemplete.Trim()
                .Replace("{namespace}", data.Namespace)
                .Replace("{clientName}", data.ClientName)
                .Replace("{methods}", data.MethodsString);
        }

        public static string MergeMethod(dynamic data)
        {
            var templete = data.ReturnType.Equals(Generater.VoidString, StringComparison.OrdinalIgnoreCase)
                ? VoidMethodTemplete
                : NoVoidMethodTemplete;

            var factoryString = MergeFactory(data);

            return templete.TrimEnd()
                .Replace("{returnType}", data.ReturnType)
                .Replace("{methodName}", data.MethodName)
                .Replace("{methodShortName}", data.MethodShortName)
                .Replace("{paramsTypeAndNames}", data.ParamsTypeAndNames)
                .Replace("{paramsNames}", data.ParamsNames)
                .Replace("{taskFactory}", factoryString);
        }

        public static string MergeFactory(dynamic data)
        {
            var templete = string.IsNullOrWhiteSpace(data.ParamsTypeAndNames)
                               ? NoParamsFactoryTemplete
                               : HasParamsFactoryTemplete;
            var result = templete.Trim()
                .Replace("{beginMethod}", data.BeginMethod)
                .Replace("{endMethod}", data.EndMethod)
                .Replace("{returnType}", data.ReturnType)
                .Replace("{paramsNames}", data.ParamsNames);
            if (data.ReturnType.Equals(Generater.VoidString, StringComparison.OrdinalIgnoreCase))
                result = result.Replace("<void>", "");

            return result;
        }

        #region FileTemplate

        public const string FileTemplate = @"

using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.Threading.Tasks;
using System.Collections.ObjectModel;

{class}

";
        #endregion

        #region ClassTemplete

        public const string ClassTemplete = @"

namespace {namespace}
{
    public partial class {clientName} 
    {
        {methods}
    }
}
";
        #endregion

        #region MethodTemplete

        public const string NoVoidMethodTemplete = @"
        public Task<{returnType}> {methodName}({paramsTypeAndNames})
        {
            {taskFactory}
        }
        public {returnType} {methodShortName}({paramsTypeAndNames})
        {
            var task = {methodName}({paramsNames});
            task.Wait();
            return task.Result;
        }

";

        public const string VoidMethodTemplete = @"
        public Task {methodName}({paramsTypeAndNames})
        {
            {taskFactory}
        }
        public void {methodShortName}({paramsTypeAndNames})
        {
            var task = {methodName}({paramsNames});
            task.Wait();
        }
";

        #endregion

        #region FactoryTemplete

        public const string HasParamsFactoryTemplete = @"
            return Task<{returnType}>.Factory.FromAsync(this.Channel.{beginMethod}, this.Channel.{endMethod}, {paramsNames}, null);
";

        public const string NoParamsFactoryTemplete = @"
            return Task<{returnType}>.Factory.FromAsync(this.Channel.{beginMethod}, this.Channel.{endMethod}, null);
";
        #endregion
    }
}